﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

    public static class RSAEncryptionist
    {
        static char rsaHashDelimiter = '.';
        public static string Compute(string text)
        {
            StringBuilder sb = new StringBuilder();
            bool first = true;
            foreach (char c in text)
            {
                string delimiter = first ? string.Empty : Char.ToString(rsaHashDelimiter);
                sb.Append(string.Format("{0}{1}", delimiter, ComputeChar(c)));
                first = false;
            }
            return sb.ToString();
        }
		public static string Compute(string text, char delimiter)
		{
			StringBuilder sb = new StringBuilder();
			bool first = true;
			foreach (char c in text)
			{
				string _delimiter = first ? string.Empty : delimiter.ToString();
				sb.Append(string.Format("{0}{1}", _delimiter, ComputeChar(c)));
				first = false;
			}
			return sb.ToString();
		}
		public static string Clear(string hash)
		{
			StringBuilder sb = new StringBuilder();
			string[] allChars = hash.Split(new char[] { rsaHashDelimiter });
			foreach (string s in allChars)
			{
				int intChar = 0;
				if (int.TryParse(s, out intChar))
				{
					sb.Append(ClearChar(intChar));
				}
			}
			return sb.ToString();
		}
		public static string Clear(string hash, char delimiter)
        {
            StringBuilder sb = new StringBuilder();
            string[] allChars = hash.Split(new char[] { delimiter });
            foreach (string s in allChars)
            {
                int intChar = 0;
                if (int.TryParse(s, out intChar))
                {
                    sb.Append(ClearChar(intChar));
                }
            }
            return sb.ToString();
        }
        public static double ComputeChar(char letter)
        {
            var p = 13;
            var q = 17;
            var N = p * q;
            var e = 7;
            //var letter = "M";
            var power = (Math.Pow(letter, e));
            var enc = power % N;
            return enc;
        }
        public static string ClearChar(int enc2)
        {
            var p = 13;
            var q = 17;
            var N = p * q;
            var e = 7;
            //var enc2 = 155; //Encrypted message
            int i;
            int d;

            // Get data from user and convert strings to integers.
            var a = (p - 1) * (q - 1);
            var b = e;
            // Save original values.
            var a0 = a;
            var b0 = b;
            // Initializations. We maintain the invariant p*a0 + q*b0 = a and r*a0 + s*b0 = b.
            p = 1; d = 0;
            var r = 0; var s = 1;
            // The algorithm:
            while (b != 0)
            {
                var c = a % b;

                var quot = Math.Floor(Convert.ToDecimal(a / b));  //Javascript doesn't have an integer division operator

                a = b;
                b = c;
                var new_r = p - quot * r; var new_s = d - quot * s;
                p = r; d = s;
                r = Convert.ToInt32(new_r); s = Convert.ToInt32(new_s);
            }
            // End of Extended Euclidean Algo

            //Loop through modular sum
            a = 1;
            var count = 1;
            for (i = 0; i < d; i++)
            {
                a = (a * enc2) % N;
                count++;

            }

            return Char.ToString(((char)a));
        }
    }

